﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SASystem.SAServiceRef;

namespace SASystem
{
    public partial class EditCategoryFrm : Form
    {
        private readonly string TREE_NODE_TYPE = "System.Windows.Forms.TreeNode";
        public EditCategoryFrm()
        {
            InitializeComponent();
        }

        private void button_AddRootCategory_Click(object sender, EventArgs e)
        {
            //add to UI.
            Guid newCateId = Guid.NewGuid();
            TreeNode newRootNode = new TreeNode();
            newRootNode.Text = "新根节点";
            this.treeView_category.Nodes.Add(newRootNode);

            //add to database.
            CategoryInfo newCateInfo = new CategoryInfo();
            newCateInfo.Name = newRootNode.Text;
            newCateInfo.Id = newCateId;
            newCateInfo.ParentId = Guid.Empty;
            newCateInfo.Idx = newRootNode.Index;

            newRootNode.Tag = newCateInfo;
            SABLL.AddCategory(newCateInfo);

            //begin edit
            newRootNode.BeginEdit();
            this.treeView_category.Refresh();
            this.treeView_category.SelectedNode = newRootNode;
        }

        private void button_AddSubCategory_Click(object sender, EventArgs e)
        {
            //get current selected node.
            //
            if (this.treeView_category.SelectedNode == null)
            {
                SABLL.ShowInfoMsg("请选择父节点!");
                return;
            }

            TreeNode parentNode = this.treeView_category.SelectedNode;

            //add to UI.
            Guid newCateId = Guid.NewGuid();
            TreeNode newRootNode = new TreeNode();
            newRootNode.Text = "新根节点";
            parentNode.Nodes.Add(newRootNode);

            //add to database.
            CategoryInfo newCateInfo = new CategoryInfo();
            newCateInfo.Name = newRootNode.Text;
            newCateInfo.Id = newCateId;
            newCateInfo.ParentId = (parentNode.Tag as CategoryInfo).Id;
            newCateInfo.Idx = newRootNode.Index;

            newRootNode.Tag = newCateInfo;
            SABLL.AddCategory(newCateInfo);

            //begin edit
            newRootNode.BeginEdit();
            this.treeView_category.Refresh();
            this.treeView_category.SelectedNode = newRootNode;
        }

        private void EditCategoryFrm_Load(object sender, EventArgs e)
        {
            SABLL.InitCategoryTreeView(this.treeView_category);
        }

        private void button_delete_Click(object sender, EventArgs e)
        {
            TreeNode curNode = this.treeView_category.SelectedNode;

            if (curNode == null) return;

            if (curNode.Nodes.Count > 0)
	        {
		        SABLL.ShowInfoMsg("分类包含子分类，无法删除！");
                return;
	        }

            Guid cateId = (curNode.Tag as CategoryInfo).Id;
            
            //TODO: check whether it has families.
            List<FamilyInfo> famInfos = SABLL.GetFamiliesByCategoryId(cateId);
            if (famInfos != null && famInfos.Count > 0)
            {
                SABLL.ShowInfoMsg(String.Format("分类[{0}]包含{1}个零部件，无法删除！",curNode.Text, famInfos.Count));
                return;
            }
            
            //
            bool result = SABLL.DeleteCategory(cateId);
            if (!result)
            {
                SABLL.ShowErrMsg(SABLL.GetLastErrMsg());
            }
            //now remove the treenode.
            curNode.Remove();
            this.treeView_category.Refresh();
        }

        private void button_edit_Click(object sender, EventArgs e)
        {
            TreeNode curNode = this.treeView_category.SelectedNode;

            curNode.BeginEdit();
        }

        private void button_save_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void treeView_category_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            TreeNode curNode = e.Node;
            if (curNode.Tag == null) return;

            Guid cateId = (curNode.Tag as CategoryInfo).Id;
            CategoryInfo updateCategoryInfo = SABLL.GetCategoryInfoByCateId(cateId);

            if (updateCategoryInfo == null)
            {
                SABLL.ShowErrMsg("获取类别失败!" + SABLL.GetLastErrMsg());
                return;
            }

            if (e.Label != null)
            {
                updateCategoryInfo.Name = e.Label;
            }

            bool result = SABLL.UpdateCategory(updateCategoryInfo);
            if (!result)
            {
                SABLL.ShowErrMsg("更新失败!" + SABLL.GetLastErrMsg());
                return;
            }
        }

        private void button_cancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void treeView_category_DragDrop(object sender, DragEventArgs e)
        {
            TreeNode moveNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");

            if (moveNode == null) return;

            Point pt = ((TreeView)sender).PointToClient(new Point(e.X, e.Y));
            TreeNode targetNode = this.treeView_category.GetNodeAt(pt);
            if (targetNode != null)
            {
                //check 
                if (moveNode.Parent != null && targetNode == moveNode.Parent)
                    return;

                TreeNode testNode = moveNode;
                if (ContainsNode(testNode, targetNode)) 
                    return;

                TreeNode newMoveNode = (TreeNode)moveNode.Clone();

                //do the change.
                targetNode.Nodes.Add(newMoveNode);
                moveNode.Remove();

                //update database.
                CategoryInfo curCateInfo = moveNode.Tag as CategoryInfo;
                if (curCateInfo != null)
                {
                    CategoryInfo curParentCateInfo = targetNode.Tag as CategoryInfo;
                    if (curParentCateInfo != null)
                    {
                        curCateInfo.ParentId = curParentCateInfo.Id;
                        curCateInfo.Idx = newMoveNode.Index;

                        if (!SABLL.UpdateCategory(curCateInfo))
                            SABLL.ShowErrMsg(SABLL.GetLastErrMsg());
                    }
                }

                //change end.

                this.treeView_category.SelectedNode = newMoveNode;
                targetNode.Expand();
            }
        }

        private bool ContainsNode(TreeNode testNode, TreeNode compareNode)
        {
            if (testNode == compareNode)
            {
                return true;
            }

            foreach (TreeNode subNode in testNode.Nodes)
            {
                if (ContainsNode(subNode, compareNode))
                    return true;
            }

            return false;
        }

        private void treeView_category_DragOver(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(TREE_NODE_TYPE))
            {
                e.Effect = DragDropEffects.Move;
            }
            else
                e.Effect = DragDropEffects.None;
        }

        private void treeView_category_ItemDrag(object sender, ItemDragEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                this.treeView_category.SelectedNode = (TreeNode)e.Item;
                DoDragDrop(e.Item, DragDropEffects.Move);
            }
        }

        private void button_Up_Click(object sender, EventArgs e)
        {
            TreeNode selectedNode = this.treeView_category.SelectedNode;

            if (selectedNode == null) return;

            TreeNode preNode = selectedNode.PrevNode;
            bool bExpand = selectedNode.IsExpanded;

            if (preNode != null)
            {
                TreeNode newNode = (TreeNode)selectedNode.Clone();

                TreeNodeCollection parentNodes;
                //do the change.
                if (selectedNode.Parent == null)
                {
                    parentNodes = this.treeView_category.Nodes;
                }
                else
                {
                    parentNodes = selectedNode.Parent.Nodes;
                }

                //change start.
                parentNodes.Insert(preNode.Index, newNode);
                selectedNode.Remove();

                //update database for category node index.
                foreach (TreeNode node in parentNodes)
                {
                    CategoryInfo curCateInfo = node.Tag as CategoryInfo;
                    if (curCateInfo != null)
                    {
                        curCateInfo.Idx = node.Index;
                        if (!SABLL.UpdateCategory(curCateInfo))
                            SABLL.ShowErrMsg(SABLL.GetLastErrMsg());
                    }
                }
                //change end

                if (bExpand) newNode.Expand();
                this.treeView_category.SelectedNode = newNode;
            }
        }

        private void button_Down_Click(object sender, EventArgs e)
        {
            TreeNode selectedNode = this.treeView_category.SelectedNode;

            if (selectedNode == null) return;

            TreeNode nextNode = selectedNode.NextNode;
            bool bExpand = selectedNode.IsExpanded;

            if (nextNode != null)
            {
                TreeNode newNode = (TreeNode)selectedNode.Clone();
                TreeNodeCollection parentNodes;
                //do the change
                if (selectedNode.Parent == null)
                {
                    parentNodes = this.treeView_category.Nodes;
                }
                else
                {
                    parentNodes = selectedNode.Parent.Nodes;
                }
                parentNodes.Insert(nextNode.Index + 1, newNode);
                selectedNode.Remove();
                //change end.

                //update database for category node index.
                foreach (TreeNode node in parentNodes)
                {
                    CategoryInfo curCateInfo = node.Tag as CategoryInfo;
                    if (curCateInfo != null)
                    {
                        curCateInfo.Idx = node.Index;
                        if (!SABLL.UpdateCategory(curCateInfo))
                            SABLL.ShowErrMsg(SABLL.GetLastErrMsg());
                    }
                }

                if (bExpand) newNode.Expand();
                this.treeView_category.SelectedNode = newNode;
            }
        }

        private void button_Edit_Click(object sender, EventArgs e)
        {
            TreeNode selectedNode = this.treeView_category.SelectedNode;

            if (selectedNode == null) return;

            selectedNode.BeginEdit();
        }
    }
}
